设计模式(三)适配器模式 & 外观模式

  1. 适配器模式
    1. 应用场景
    2. 总结
  2. 外观模式
    1. 应用场景
    2. 总结

适配器模式

应用场景

鸭子中有绿头鸭、红头鸭等,现在还缺一点鸭子的品种,想用火鸡冒充鸭子。

public interface Duck {
    public void quack();
    public void fly();
}

//绿头鸭
public class MallardDuck implements Duck {
    public void quack() {
        System.out.println("Quack");
    }

    public void fly() {
        System.out.println("I'm flying");
    }
}

//火鸡
public interface Turkey {
    public void gobble();
    public void fly();
}

public class WildTurkey implements Turkey {
    public void gobble() {
       System.out.println("Gobble gobble");
    }

    public void fly() {
       System.out.println("I'm flying a short distance");
    }
}

//适配器
public class TurkeyAdapter implements Duck {
    Turkey turkey;

    public TurkeyAdapter(Turkey turkey) {
        this.turkey = turkey;
    }

    public void quack() {
        turkey.gobble();
    }

    public void fly() {
        for (int i=0; i < 5; i++) {
           turkey.fly();
        }
    }
}

客户通过目标接口调用适配器的方法对适配器发出请求,适配器使用被适配者接口把请求转换成被适配者的一个或多个调用接口,客户接收到调用的结果,但并未察觉这一切是适配器做起转换作用。

适配器模式是将一个类的接口,转换成客户期望的另一个接口。适配器让原本接口不兼容的类可以合作无间。

总结

当需要使用现有的类而其接口不符合需要时,使用适配器。

延伸,适配器模式有两种形式,对象适配和类适配,类适配其实就是用(java)多重继承实现,效果一样但不够灵活。和装饰者比较,适配器是包装了一个对象并改变它的接口,装饰者是将对象包装起来后增加新行为和责任。

外观模式

应用场景

假设想看一出电影大片,但看之前要准备一大堆操作,执行如下

popper.on();
popper.pop();
lights.dim(10);
screen.down();
projector.on();
projector.setInput(dvd);
projector.wideScreenMode();
amp.on();
amp.setDvd(dvd);
amp.setSurroundSound();
amp.setVolume(5);
dvd.on();
dvd.play(movie);

当你想关闭时,又是一堆操作。

我们使用组合的方式将各个子系统汇集起来,然后实现统一个的接口来优化

public class HomeTheaterFacade {
    Amplifier amp;
    Tuner tuner;
    DvdPlayer dvd;
    CdPlayer cd;
    Projector projector;
    TheaterLights lights;
    Screen screen;
    PopcornPopper popper;

    public HomeTheaterFacade(Amplifier amp,Tuner tuner,DvdPlayer dvd,CdPlayer cd,Projector projector,Screen screen,TheaterLights lights,PopcornPopper popper) {
        this.amp = amp;
        this.tuner = tuner;
        this.dvd = dvd;
        this.cd = cd;
        this.projector = projector;
        this.screen = screen;
        this.lights = lights;
        this.popper = popper;
    }

    public void watchMovie(String movie) {
        System.out.println("Get ready to watch a movie ... ");
        popper.on();
        popper.pop();
        lights.dim(10);
        screen.down();
        projector.on();
        projector.setInput(dvd);
        projector.wideScreenMode();
        amp.on();
        amp.setDvd(dvd);
        amp.setSurroundSound();
        amp.setVolume(5);
        dvd.on();
        dvd.play(movie);
    }

    public void endMovie() {
        System.out.println("Shutting movie theater down ... ");
        popper.off();
        lights.on();
        screen.up();
        projector.off();
        amp.off();
        dvd.stop();
        dvd.eject();
        dvd.off();
    }
}

这样就实现了外观模式了。外观模式提供了一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用。也可以理解为是一个包装了多个被适配者的适配器。

外观模式和适配器模式的设计原则是,最少知识原则(又叫“墨忒耳法则”),只和你的密友谈话,不要让太多的类耦合在一起,避免修改系统的一部分而影响到其它部分。

再举一些避免耦合过多类的示例

public float getTemp1() {
    Thermometer thermometer = station.getThermometer();
    return thermometer.getTemperature();
}

public float getTemp2() {
    return station.getTemperature();
}

总结

当需要简化并统一一个很大的接口或者一群复杂的接口时,使用外观,从一个复杂的子系统中解耦。


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 mingfungliu@gmail.com

文章标题:设计模式(三)适配器模式 & 外观模式

文章字数:898

本文作者:Mingfung

发布时间:2019-02-11, 15:10:00

最后更新:2019-02-12, 14:34:04

原始链接:http://blog.ifungfay.com/设计模式/设计模式(三)适配器模式 & 外观模式/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录
×

喜欢就点赞,疼爱就打赏

宝贝回家